package com.imooc.pay.service.impl;

import com.google.gson.Gson;
import com.imooc.pay.dao.PayInfoMapper;
import com.imooc.pay.enums.PayPlatformEnum;
import com.imooc.pay.pojo.PayInfo;
import com.imooc.pay.service.IPayService;
import com.lly835.bestpay.enums.BestPayPlatformEnum;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.enums.OrderStatusEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.service.BestPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;

@Slf4j
@Service
@SuppressWarnings("ALL")
public class PayServiceImpl implements IPayService {

    private final static String QUEUE_PAY_NOTIFY="payQueue";

    @Autowired
    private BestPayService bestPayService;

    @Autowired
    private PayInfoMapper payInfoMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;


    @Override
    public PayResponse create(String orderId, BigDecimal amount, BestPayTypeEnum bestPayTypeEnum) {

        //写入数据库
        PayInfo payInfo = new PayInfo(Long.parseLong(orderId),
                PayPlatformEnum.getByBestPayTypeEnum(bestPayTypeEnum).getCode(),
                OrderStatusEnum.NOTPAY.name(),
                amount,
                new Date(),
                new Date());
        int i = payInfoMapper.insertSelective(payInfo);
        if (bestPayTypeEnum != BestPayTypeEnum.WXPAY_NATIVE
                && bestPayTypeEnum != BestPayTypeEnum.ALIPAY_PC) {
            throw new RuntimeException("暂时不支持的支付类型");
        }
        //发起支付
        PayRequest payRequest = new PayRequest();
        payRequest.setPayTypeEnum(bestPayTypeEnum); //支付方式
        payRequest.setOrderId(orderId);
        payRequest.setOrderName("7379374-native支付订单");
        payRequest.setOrderAmount(amount.doubleValue());
        //payRequest.setOpenid("openid_xxxxxx");
        PayResponse payResponse = bestPayService.pay(payRequest);
        log.info("发起支付response==>>{}", payResponse);
        return payResponse;
    }

    /**
     * 异步通知处理
     *
     * @param notifyData
     */
    @Override
    public String asyncNotify(String notifyData) {

        //1.签名校验 封装好了  ctrl+alt+b查看实现类
        //签名，状态的校验
        PayResponse payResponse = bestPayService.asyncNotify(notifyData);
        log.info("异步通知payResponse==>{}", payResponse);

        //2.金额校验（从数据库查订单）
        PayInfo payInfo = payInfoMapper.selectByOrderNum(Long.parseLong(payResponse.getOrderId()));//Long.parseLong(payResponse.getOrderId())
        log.info("从数据库中查到的订单信息==>>{}",payInfo);
        if (null==payInfo){
            //正常情况下是不会发生的，情况比较严重，发出告警：钉钉，短信
            throw new RuntimeException("通过orderNum是null!");
        }
        //如果支付不为成功状态
        if (!payInfo.getPlatformStatus().equals(OrderStatusEnum.SUCCESS.name())) {
            System.err.println("比对数据库订单金额与微信异步通知金额是否一致");
            //-1, 0, or 1 as this {@code BigDecimal} is numerically
            //     *          less than, equal to, or greater than
            if (payInfo.getPayAmount().compareTo(BigDecimal.valueOf(payResponse.getOrderAmount()))!=0) {
                throw new RuntimeException("异步通知中的金额与数据库中的不一致！orderNum="+payResponse.getOrderId());
            }
            //3.如果没问题，修改订单支付状态
            payInfo.setPlatformStatus(OrderStatusEnum.SUCCESS.name());
            payInfo.setUpdateTime(new Date());
            payInfo.setPlatformNumber(payResponse.getOutTradeNo());
            payInfoMapper.updateByPrimaryKeySelective(payInfo);
        }

        //4.告诉微信/支付宝不要再通知了,一定要写对，否则微信/支付宝服务器会不断重发通知
        // TODO mq发送消息给mall
        amqpTemplate.convertAndSend(QUEUE_PAY_NOTIFY,new Gson().toJson(payInfo));

        if (payResponse.getPayPlatformEnum() == BestPayPlatformEnum.WX) {
            System.err.println("告诉微信/支付宝不要再通知了");
            return "<xml>\n" +
                    "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                    "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                    "</xml>";
        } else if (payResponse.getPayPlatformEnum() == BestPayPlatformEnum.ALIPAY) {
            return "success";
        }

        throw new RuntimeException("异步通知中错误的支付平台……");

    }

    @Override
    public String testSql() {
        System.err.println("进入test方法");
        PayInfo payInfo = payInfoMapper.selectByOrderNum(88888888L);
        return payInfo.toString();
    }

    @Override
    public PayInfo queryStatus(String orderId) {
        return payInfoMapper.selectByOrderNum(Long.parseLong(orderId));
    }
}
